﻿using Furion;
using Furion.Authorization;
using Furion.DataEncryption;
using FurStudy.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace FurStudy.Web.Core
{
    /// <summary>
    /// JWT授权自定义处理程序
    /// </summary>
    public class JwtHandler : AppAuthorizeHandler // Furion框架提供了AppAuthorizeHandler策略授权处理程序提供基类，只需要创建自己的Handler继承它即可
    {
        /// <summary>
        /// 请求管道
        /// </summary>
        /// <param name="context"></param>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public override Task<bool> PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext)
        {
            // 此处已经自动验证 Jwt token的有效性了，无需手动验证

            // 检查权限，如果方法是异步的就不用 Task.FromResult 包裹，直接使用 async/await 即可
            return Task.FromResult(CheckAuthorzie(httpContext));
        }

        /// <summary>
        /// 检查权限
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        private static bool CheckAuthorzie(DefaultHttpContext httpContext)
        {
            // 获取权限特性
            var securityDefineAttribute = httpContext.GetMetadata<SecurityDefineAttribute>();
            if (securityDefineAttribute == null) return true;

            return false;  // 查询数据库返回是否有权限
        }

        /// <summary>
        /// 重写Handler进行完全自定义授权
        /// 重写Handler添加自动刷新收取逻辑
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task HandleAsync(AuthorizationHandlerContext context)
        {
            #region 完全自定义授权

            // 常规授权（可以判断是不是第三方）
            var isAuthenticated = context.User.Identity.IsAuthenticated;

            // 第三方授权自定义
            List<IAuthorizationRequirement> pendingRequirements = new List<IAuthorizationRequirement>(); // 第三方授权合集，此处为了程序书写先声明为空
            if (isAuthenticated) // 如果是第三方
            {
                foreach (var item in pendingRequirements)
                {
                    // 授权成功
                    context.Succeed(item);
                }
            }
            else
                context.Fail(); // 授权失败

            #endregion

            #region 自动刷新收取

            // 自动刷新token
            if (JWTEncryption.AutoRefreshToken(context, context.GetCurrentHttpContext()))
            {
                await AuthorizeHandleAsync(context);
            }
            else
                context.Fail(); // 授权失败

            #endregion

            // 获取Jwt存储的信息
            var userId = App.User?.FindFirstValue("键");
        }
    }
}
